import {Injectable} from '@angular/core';
import {Http, Response, Headers, RequestOptions} from '@angular/http';
import {Router} from"@angular/router";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/timeout';
// 引入localstorage 服务
import {LocalstorageProvider} from '../localstorage/localstorage';
import { Network } from '@ionic-native/network';

/**
 * HTTP请求服务
 */
@Injectable()
export class HttphandleProvider{

  private servicesroot: String;
  private headerObj: Headers;
  private connectServer = {
    testlocal: 'http://localhost:3000',
    test1: 'http://192.168.7.129:8686', // yazhao
    test2: 'http://192.168.7.113:8686', // haojie
    test3: 'http://192.168.7.125:8686', // xue,
    test4: 'http://192.168.0.100:8686', // xinli
    test5: 'http://192.168.7.192:8686'
  };
  private netStatus: Boolean = true;
  private account: any;

  constructor(public http: Http,
              public loc: LocalstorageProvider,
              private network: Network,
              private route: Router,
            ) {

    this.headerObj = new Headers({
      'Authorization': 'Basic Y2xpZW50OnNlY3JldA=='
    })
    // 订阅离线消息
    this.network.onDisconnect().subscribe(() => {
      this.netStatus = false
    });
    // 订阅上线消息
    this.network.onConnect().subscribe(() => {
      this.netStatus = true
    })
  }
  // 获取请求地址
  getServeAddress(){
    var result:String
    var developFlag = this.loc.get("developFlag")
    var subdomain = JSON.parse(localStorage.getItem('subdomain'))['value']
    if (subdomain.indexOf('test') > -1) {
      result = this.connectServer[subdomain]
    } else {
      if (developFlag) {
        result = `http://${subdomain}.wenshidata.com`;
      } else {
        result = `http://${subdomain}.iemes.cn`;
      }
    }
    return result;
  }

  /**
   * get方式请求
   * @param {string} url     //url
   * @param paramObj      //json对象 如:{name:'大见',age:'23'}
   * @return {Promise<never | {}>}
   */
  get(url: string, paramObj?: any) {
    if (!this.netStatus) {
      return new Promise((resolve, reject) => {
        reject('网络不可用')
      })
    } else {
      this.servicesroot = this.getServeAddress()
      if (this.loc.get('token')) {
        this.headerObj.set('Authorization', 'bearer ' + this.loc.get('token')['access_token'])
      }
      let options = new RequestOptions({headers: this.headerObj});
      if (!paramObj) {
        return this.http.get(this.servicesroot + url, options)
          .timeout(10 * 1000)
          .toPromise()
          .then(this.extractData)
          .catch(this.handleError);
      } else {
        return this.http.get(this.servicesroot + url + this.toQueryString(paramObj), options)
          .timeout(10 * 1000)
          .toPromise()
          .then(this.extractData)
          .catch(this.handleError);
      }
    }
  }

  /**
   * post方式请求
   * @param {string} url
   * @param body       //如：paramObj:{name:'大见',age:'23'}
   * @param {string} contentType      //post请求的编码方式  application/x-www-form-urlencoded  multipart/form-data   application/json   text/xml
   * @return {Promise<never | {}>}
   */
  post(url: string, body: any = {}) {
    if (!this.netStatus) {
      return new Promise((resolve, reject) => {
        reject('网络不可用')
      })
    } else {
      this.servicesroot = this.getServeAddress()
      if (this.loc.get('token')) {
        this.headerObj.set('Authorization', 'bearer ' + this.loc.get('token')['access_token'])
      }
      this.headerObj.set('Content-Type', 'application/json')
      let options = new RequestOptions({headers: this.headerObj});
      return this.http.post(this.servicesroot + url, JSON.stringify(body), options)
        .timeout(10 * 1000)
        .toPromise()
        .then(this.extractData)
        .catch(this.handleError);
    }
  }

  getToken(success, error?) {
    if (!this.netStatus) {
      if (error) {
        error && error({
          name: 'network',
          message: '网络不可用'
        })
      } else {
        return new Promise((resolve, reject) => {
          reject('网络不可用')
        })
      }
    } else {
      this.servicesroot = this.getServeAddress()
      this.account = this.loc.get('account')
      if (!this.account) {
        this.route.navigate(['login']) // 信息不存在登录
        return false
      }
      this.headerObj.set('Content-Type', 'application/x-www-form-urlencoded')
      this.headerObj.set('Authorization', 'Basic Y2xpZW50OnNlY3JldA==')
      let options = new RequestOptions({headers: this.headerObj});
      return this.http.post(this.servicesroot + '/app/rest/v2/oauth/token', this.toBodyString({
        grant_type: 'password',
        username: this.account.username,
        password: this.account.password
      }), options)
        .timeout(10 * 1000)
        .subscribe(res => {
          if (success) {
            success && success(res)
          } else {
            this.extractData(res)
          }
        },err => {
          if (error) {
            error && error(err)
          } else {
            this.handleError(err)
          }
        })
        // .toPromise()
        // .then(res => {
        //   if (success) {
        //       success && success(res)
        //   } else {
        //       this.extractData(res)
        //   }
        // })
        // .catch(err => {
        //   if (error) {
        //       error && error(err.json())
        //   } else {
        //       this.handleError(err)
        //   }
        // });
    }
  }

  /**
   * get请求参数处理
   *  对于get方法来说，都是把数据串联在请求的url后面作为参数，如果url中出现中文或其它特殊字符的话，很常见的一个乱码问题就要出现了
   *  url拼接完成后，浏览器会对url进行URL encode，然后发送给服务器，URL encode的过程就是把部分url做为字符，按照某种编码方式（如：utf-8,gbk等）编码成二进制的字节码
   * 不同的浏览器有不同的做法，中文版的浏览器一般会默认的使用GBK，通过设置浏览器也可以使用UTF-8，可能不同的用户就有不同的浏览器设置，也就造成不同的编码方式，
   * 所以通常做法都是先把url里面的中文或特殊字符用 javascript做URL encode，然后再拼接url提交数据，也就是替浏览器做了URL encode，好处就是网站可以统一get方法提交数据的编码方式。
   * @param obj　参数对象
   * @return {string}　参数字符串
   * @example
   *  声明: var obj= {'name':'大见',age:23};
   *  调用: toQueryString(obj);
   *  返回: "?name=%E5%B0%8F%E5%86%9B&age=23"
   */
  private toQueryString(obj) {
    let ret = [];
    for (let key in obj) {
      key = encodeURIComponent(key);
      let values = obj[key];
      if (values && values.constructor == Array) {//数组
        let queryValues = [];
        for (let i = 0, len = values.length, value; i < len; i++) {
          value = values[i];
          queryValues.push(this.toQueryPair(key, value));
        }
        ret = ret.concat(queryValues);
      } else { //字符串
        ret.push(this.toQueryPair(key, values));
      }
    }
    return '?' + ret.join('&');
  }

  /**
   *  post请求参数处理
   * @param obj
   * @return {string}
   *  声明: var obj= {'name':'大见',age:23};
   *  调用: toQueryString(obj);
   *  返回: "name=%E5%B0%8F%E5%86%9B&age=23"
   */
  private toBodyString(obj) {
    let ret = [];
    for (let key in obj) {
      key = encodeURIComponent(key);
      // key = key;
      let values = obj[key];
      if (values && values.constructor == Array) {//数组
        let queryValues = [];
        for (let i = 0, len = values.length, value; i < len; i++) {
          value = values[i];
          queryValues.push(this.toQueryPair(key, value));
        }
        ret = ret.concat(queryValues);
      } else { //字符串
        ret.push(this.toQueryPair(key, values));
      }
    }
    return ret.join('&');

    // return JSON.stringify(obj);
  }

  private toQueryPair(key, value) {
    if (typeof value == 'undefined') {
      return key;
    }
    return key + '=' + encodeURIComponent(value === null ? '' : String(value));
    // return key + '=' +(value === null ? '' : String(value));
  }

  private extractData(res: Response) {
    try{
      let body = res.json();
      return body || {};
    }catch(e){
      return res['_body']
    }
  }

  private handleError(error:Response | any) {
    var errMsg:String = "";
    var errObj:any = null;
    var errInfo:any = {
        errMsg:String,
        errObj:Object
    };
    if (error instanceof Response) {
        const body = error.json() || '';
        errMsg = body.error || JSON.stringify(body);
        // errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        switch(error.status){
            case 0:
              errMsg = "服务器繁忙"
              break;
            case 401:
                errMsg = ""
                errObj = error
                break;
            case 404:
                errMsg = "请检查网络设置"
                break;
            case 405:
                errMsg = "工厂子域名不存在"
                errObj = error
                break;
            case 400:
                errObj = error
                break;
            case 500:
            case 502:
                errMsg = "服务器繁忙"
                break;
            default:
                errMsg = error.status+'' || '请检查网络设置'
        }
    } else {
        if (error.message == "Timeout has occurred") {
            errMsg = "请求超时"
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
    }
    errInfo.errMsg = errMsg
    errInfo.errObj = errObj
    console.log(errInfo)
    if (errInfo.errObj) {
        return Promise.reject(errInfo.errObj);
    } else {
        return Promise.reject(errInfo.errMsg);
    }
  }


}
